package com.zy.kotlinbaselibrary.net

import android.util.Log
import com.zy.BaseLibraryConfig
import com.zy.kotlinbaselibrary.log.XLog
import okhttp3.*
import okio.Buffer
import java.io.IOException

/**
 * Log拦截器，用于显示请求之前的log和请求之后的log
 */
class LogInterceptor : Interceptor {

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        // 请求之前调用
        val request = chain.request()
        logRequest(request)
        // 请求之后调用
        val response = chain.proceed(request)
        return logResponse(response)
    }

    // 请求的参数
    private fun logRequest(request: Request) {
        try {
            val url = request.url.toString()
            val headers = request.headers

            XLog.d(TAG, "url:.." + url + "...:method : " + request.method)

            if (headers.size > 0) {
                XLog.d(TAG, "headers : $headers")
            }

            val requestBody = request.body
            if (requestBody != null) {
                val mediaType = requestBody.contentType()
                if (mediaType != null) {
                    if (isText(mediaType)) {
                        XLog.d(TAG, "params : " + bodyToString(request))
                    } else {
                        XLog.d(TAG, "params : " + " maybe [file part] , too large too print , ignored!")
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }


    // 相应的参数
    private fun logResponse(response: Response): Response {

        try {
            val builder = response.newBuilder()
            val clone = builder.build()
            var body = clone.body
            if (body != null) {
                val mediaType = body.contentType()
                if (mediaType != null) {
                    if (isText(mediaType)) {
                        val resp = body.string()
                        XLog.json(Log.DEBUG, TAG, resp)
                        body = ResponseBody.create(mediaType, resp)
                        return response.newBuilder().body(body).build()
                    } else {
                        XLog.d(TAG, "data : " + " maybe [file part] , too large too print , ignored!")
                    }
                }
            }

        } catch (e: Exception) {
            e.printStackTrace()
        }

        return response
    }

    private fun isText(mediaType: MediaType?): Boolean {
        return if (mediaType == null) false else "text" == mediaType.subtype
                || "json" == mediaType.subtype
                || "xml" == mediaType.subtype
                || "html" == mediaType.subtype
                || "webviewhtml" == mediaType.subtype
                || "x-www-form-urlencoded" == mediaType.subtype

    }

    private fun bodyToString(request: Request): String {
        try {
            val copy = request.newBuilder().build()
            val buffer = Buffer()
            copy.body!!.writeTo(buffer)
            return buffer.readUtf8()
        } catch (e: IOException) {
            return "something error when show requestBody."
        }

    }

    companion object {

        val TAG = BaseLibraryConfig.INTERCEPTOR_LOG_TAG
    }
}
